/**
 * zilla-sandbox AES加密解密SDK
 */
var fileEncryptor = require('./lib/fileEncryptor.js');
fileEncryptor = new fileEncryptor();

var streamHelper = require('./lib/streamHelper.js');

var util = require('util');
var fs = require('fs');

//------------------------捕捉全局异常-----------------//
process.on('uncaughtException', function(err) {
	// console.log(util.inspect(err));
	console.log('请检查资源是否存在？\n');
	console.log(err);
	process.exit();
});

/**
 * [showCmdMenu description] 显示菜单
 * @return {[type]} [description]
 */
function showCmdMenu() {
	console.log('\n\n\t-- @email:heyaowen@foreveross.com-- Vector Ho --\t');
	console.log('\t-- 欢迎使用zilla-sandbox安全沙盒SDK，使用SDK请遵循以下指令规则 --\n');
	console.log('   ps：确保资源编码为' + util.inspect('utf8', {colors: true}) + ', AES对称加、解密，另特殊字符' + util.inspect('@', {colors: true}) + '为分隔符！慎用！');
	console.log('       数据无价！！！使用本SDK前请备份，且用且珍惜...\n');
	console.log('| 1.加密文件：输入指令(ef@key@file)如：' + util.inspect('ef@abcdf0900@D:/sandbox.html', {colors: true}) + ' |');
	console.log('| 2.加密文件夹：输入指令(ed@key@path)如：' + util.inspect('ed@abcdf0900@D:/sandbox', {colors: true}) + ' |');
	console.log('| 3.解密文件：输入指令(格式df@key@file)如：' + util.inspect('df@abcdf0900@D:/sandbox.html', {colors: true}) + ' |');
	console.log('| 4.解密文件夹：输入指令(dd@key@path)如：' + util.inspect('dd@abcdf0900@D:/sandbox', {colors: true}) + ' |');
	console.log('| 5.生成加密列表文件：输入指令(fs@path)如：' + util.inspect('fs@D:/sandbox', {colors: true}) + ' |');
	console.log('| 6.退出SDK：输入指令：' + util.inspect('q', {colors: true}) + ' |\n\n  准备接收指令...\n');
}

/**
 * [readUntilEnter description] 读取一行指令
 * @param  {Function} cb [description]
 * @return {[type]}      [description]
 */
function readUntilEnter(cb) {
	process.stdin.resume(); // 准输入流默认是暂停 (pause) 的，所以必须要调用 process.stdin.resume() 来恢复 (resume) 接收。
	process.stdin.setEncoding('utf8');

	// 用户输指令字按回车
	process.stdin.on('data', function(chunk) {
		cb(chunk);
	});

	// 指令结束
	process.stdin.on('end', function () {
		process.stdout.write('\nshell end...');
	});
}

/**
 * [isIgnore description] 是否忽略此文件，即忽略后就不加密、不解密
 * @param  {[type]} fileName [description]
 * @return {[type]}      [description]
 */
function isIgnore(fileName) {
	var pattern = /\..+Old$/; // 自己生成的文件忽略
	return pattern.test(fileName);
}

/**
 * [fileHelper description] 文件夹递归
 * @param  {[type]} file_dir [description] 资源绝对路径
 * @key  {[type]} key [description] 加密用的key
 * @type  {[type]} type [description] 0解密 1加密
 * @return {[type]}          [description]
 */
function fileHelper(file_dir, key, type, callback) {
	var callMyself = arguments.callee;
	if (fs.lstatSync(file_dir).isDirectory()) {
		try {
			var files = fs.readdirSync(file_dir);
		} catch(err) {
			console.log('检查资源是否存在？路径是否有问题？%s', err);
			return;
		}
    files.forEach(function(item, index, array) {
      // if (isIgnore(item)) { // 白名单
      //   return;
      // }
      callMyself(file_dir + '/' + item, key, type, callback);  // 递归
    });
	} else {
		if (type === 1) { //【加密】
			fileEncryptor.encrypt(file_dir, key, callback);
		} else if(type === 0) { // 【解密】
			fileEncryptor.decrypt(file_dir, key, callback);
		}
	}
}


//----------------进入shell---------------------//
showCmdMenu();

readUntilEnter(function(reuslt) {
	var sgin = false;
	// 最后有个\r\n,去掉
	if(require('os').platform().substring(0, 3) === 'win')  { // win32、64
		reuslt = reuslt.split('\r\n')[0];
	} else { // linux、unix
		reuslt = reuslt.split('\n')[0];
	}

	var cmds = reuslt.split('@'); // [指令，key，资源绝对路径]
	console.log(' 输入信息：' + cmds);

	/**
	 * [cmd description] 解析指令
	 */
	if(cmds[0] === 'q') {
		process.stdin.pause(); // 结束交互，此时不接受用户指令
		console.log('  ' + util.inspect('退出安全沙盒SDK...', {colors: true}));
		// process.exit();

	} else if(cmds[0] === 'ef') {
		console.log('  ' + util.inspect('开始进行文件加密...', {colors: true}));

		process.stdin.pause(); // 结束交互，此时不接受用户指令
		fileEncryptor.encrypt(cmds[2], cmds[1], function() {
			process.stdin.resume(); // 恢复交互
			// console.log('原文件备份为同路径Old类型文件...' );
			console.log('\n  准备接收指令...\n');
		});

	} else if(cmds[0] === 'ed') {
		console.log('  ' + util.inspect('开始进行文件夹加密...', {colors: true}));
		process.stdin.pause(); // 结束交互，此时不接受用户指令

		//-----------------------递归处理：new features 20140627------------------------//
		fileHelper(cmds[2], cmds[1], 1, function() {
			// console.log('原文件备份为同路径Old类型文件...' );
			if(!sgin) {
				console.log('\n  准备接收指令...\n');
				process.stdin.resume();
				sgin = true;
			}
		});

		// fs.readdir(cmds[2], function(err, files) { // files文件名称数组
		// 	if(err) {
		// 		console.log('检查资源是否存在？路径是否有问题？%s', err);
		// 	} else {
		// 		var p = 0;
		// 		files.forEach(function(item, index, array) {
		// 			if (isIgnore(item)) {
		// 				p++;
		// 				return;
		// 			}
		// 			fileEncryptor.readWriteStream(cmds[2] + '/' + item, cmds[2] + '/' + item + 'New', 1, cmds[1], function() {
		// 				if(index === array.length - 1 - p) {
		// 					// console.log('原文件备份为同路径Old类型文件...' );
		// 					console.log('\n  准备接收指令...\n');
		// 				}
		// 			});

		// 		});
		// 		/*for (var i = files.length - 1; i >= 0; i--) {
		// 			if (isIgnore(files[i])) {
		// 				continue;
		// 			}
		// 			fileEncryptor.readWriteStream(cmds[2] + '/' + files[i], cmds[2] + '/' + files[i] + 'New', 1, cmds[1], false);
		// 		}*/
		// 		process.stdin.resume();
		// 	}
		// });
	} else if(cmds[0] === 'df') {
		console.log('  ' + util.inspect('开始进行文件解密...', {colors: true}));

		process.stdin.pause(); // 结束交互，此时不接受用户指令
		fileEncryptor.decrypt(cmds[2], cmds[1], function() {
			process.stdin.resume(); // 恢复交互
			// console.log('原文件备份为同路径Old类型文件...' );
			console.log('\n  准备接收指令...\n');
		});
	} else if(cmds[0] === 'dd') {
		console.log('  ' + util.inspect('开始进行文件夹解密...', {colors: true}));
		process.stdin.pause(); // 结束交互，此时不接受用户指令

		//-----------------------递归处理：new features 20140627------------------------//
		fileHelper(cmds[2], cmds[1], 0, function() {
			// console.log('原文件备份为同路径Old类型文件...' );
			if(!sgin) {
				console.log('\n  准备接收指令...\n');
				process.stdin.resume();
				sgin = true;
			}
		});

		// fs.readdir(cmds[2], function(err, files) {
		// 	if(err) {
		// 		console.log('检查资源是否存在？路径是否有问题？' + err);
		// 	} else {
		// 		var p = 0;
		// 		files.forEach(function(item, index, array) {
		// 			if (isIgnore(item)) {
		// 				p++;
		// 				return;
		// 			}
		// 			fileEncryptor.readWriteStream(cmds[2] + '/' + item, cmds[2] + '/' + item + 'New', 0, cmds[1], function() {
		// 				if(index === array.length - 1 - p) {
		// 					// console.log('原文件备份为同路径Old类型文件...' );
		// 					console.log('\n  准备接收指令...\n');
		// 				}
		// 			});
		// 		});
		// 		/*for (var i = files.length - 1; i >= 0; i--) {
		// 			if (isIgnore(files[i])) {
		// 				continue;
		// 			}
		// 			fileEncryptor.readWriteStream(cmds[2] + '/' + files[i], cmds[2] + '/' + files[i] + 'New', 0, cmds[1], false);
		// 		}*/
		// 		process.stdin.resume(); // 允许用户输入指令
		// 	}
		// });
	} else if(cmds[0] === 'fs') {
		console.log('  ' + util.inspect('开始生成加密文件列表...', {colors: true}));
		process.stdin.pause(); // 结束交互，此时不接受用户指令

		fs.readdir(cmds[1], function(err, files) {
			if(err) {
				console.log('请检查资源是否存在？路径是否有问题？' + err);
			} else {
				var file = files.toString().replace(/,sandbox.json/, '');
				file = file.replace(/,\w*\.\w*Old/g, ''); // Old文件一般不会在第一个出现  /g代表全局匹配file
				// 生成加密列表
				streamHelper.writeStream(file, cmds[1], function() {
					console.log('\n 生成文件为' + cmds[1] + '/sandbox.json');
					console.log('\n  准备接收指令...\n');
					process.stdin.resume();
				});
			}
		});
	} else {
		console.log('  ' + util.inspect('请输入正确指令！注意@符号为分隔符！慎用！', {colors: true}));
		showCmdMenu();
	}
});